package com.swift.violent.mainstay.security.service;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.swift.violent.mainstay.common.util.IpUtil;
import com.swift.violent.mainstay.common.util.SecurityUtil;
import com.swift.violent.mainstay.common.util.ServletUtil;
import com.swift.violent.mainstay.security.model.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * token验证处理
 *
 * @author ruoyi
 */
@Component
@SuppressWarnings("ALL")
public class TokenService {
    @Autowired
    private RedisService redisService;
    private final static long TOKEN_EXPIRE = 720;
    private final static long EXPIRE_TIME = TOKEN_EXPIRE * 60;
    private final static String ACCESS_TOKEN = "login_tokens:";

    /**
     * The constant MILLIS_SECOND.
     */
    protected static final long MILLIS_SECOND = 1000;

    /**
     * 创建令牌
     *
     * @param loginUser the login user
     *
     * @return the map
     */
    public Map<String, Object> createToken(LoginUser loginUser) {
        final String token = IdUtil.simpleUUID();
        loginUser.setToken(token)
                .setUserid(loginUser.getSysUser().getUserId())
                .setUsername(loginUser.getSysUser().getUserName())
                .setIpaddr(IpUtil.getIpAddr(ServletUtil.getRequest()));
        refreshToken(loginUser);
        redisService.setCacheObject(ACCESS_TOKEN + token, loginUser, EXPIRE_TIME, TimeUnit.SECONDS);
        return MapUtil.builder(new HashMap<String, Object>(2))
                .put("access_token", token)
                .put("expires_in", EXPIRE_TIME)
                .build();
    }

    /**
     * 获取用户身份信息
     *
     * @return 用户信息 login user
     */
    public LoginUser getLoginUser() {
        return getLoginUser(ServletUtil.getRequest());
    }

    /**
     * 获取用户身份信息
     *
     * @param request the request
     *
     * @return 用户信息 login user
     */
    public LoginUser getLoginUser(HttpServletRequest request) {
        final String token = SecurityUtil.getToken(request);
        if (StrUtil.isNotEmpty(token)) {
            return redisService.getCacheObject(getTokenKey(token));
        }
        return null;
    }

    /**
     * 设置用户身份信息
     *
     * @param loginUser the login user
     */
    public void setLoginUser(LoginUser loginUser) {
        if (Objects.nonNull(loginUser) && StrUtil.isNotEmpty(loginUser.getToken())) {
            refreshToken(loginUser);
        }
    }

    /**
     * Del login user.
     *
     * @param token the token
     */
    public void delLoginUser(String token) {
        if (StrUtil.isNotEmpty(token)) {
            redisService.deleteObject(getTokenKey(token));
        }
    }

    /**
     * 刷新令牌有效期
     *
     * @param loginUser 登录信息
     */
    public void refreshToken(LoginUser loginUser) {
        loginUser.setLoginTime(System.currentTimeMillis())
                .setExpireTime(loginUser.getLoginTime() + EXPIRE_TIME * MILLIS_SECOND);
        redisService.setCacheObject(getTokenKey(loginUser.getToken()), loginUser, EXPIRE_TIME, TimeUnit.SECONDS);
    }

    private String getTokenKey(String token) {
        return ACCESS_TOKEN + token;
    }
}